package com.ziq.zcamp.util;

import static com.ziq.zcamp.api.service.APIKt.BASE_IMAGE_URL;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Animatable;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.facebook.binaryresource.BinaryResource;
import com.facebook.binaryresource.FileBinaryResource;
import com.facebook.cache.common.CacheKey;
import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.cache.DefaultCacheKeyFactory;
import com.facebook.imagepipeline.common.ImageDecodeOptions;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.core.ImagePipelineFactory;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.io.File;

public class ImageUtil {

	public static final int imageMaxSize = 7000;

	/**
	 * 防止重复而导致的闪烁
	 */

	public static void updateImageFromNetwork(SimpleDraweeView view, String url) {
		updateImageFromNetwork(view, url, 0, 0, imageMaxSize, ImageRequest.CacheChoice.DEFAULT, null);
	}

	public static void updateImageFromNetwork(SimpleDraweeView view, String url, MyBaseControllerListener controllerListener) {
		updateImageFromNetwork(view, url, 0, 0, imageMaxSize, ImageRequest.CacheChoice.DEFAULT, controllerListener);
	}

	public static void updateImageFromNetwork(SimpleDraweeView view, String url, ImageRequest.CacheChoice cacheChoice) {
		updateImageFromNetwork(view, url, 0, 0, imageMaxSize, cacheChoice, null);
	}

	public static void updateImageFromNetwork(SimpleDraweeView view, String url, final int width, final int height, final int maxSizeForWH) {
		updateImageFromNetwork(view, url, width, height, maxSizeForWH, ImageRequest.CacheChoice.DEFAULT, null);
	}

	/**
	 * 绑定图片到SimpleDraweeView
	 * @param view SimpleDraweeView
	 * @param url 图片路径
	 * @param imageWidth 图片的真实大小
	 * @param imageHeight 图片的真实大小
	 */
	public static void updateImageFromNetwork(SimpleDraweeView view, String url, final int imageWidth , final int imageHeight){
		boolean isLongImage = imageHeight > (imageWidth * 2);
		if (isLongImage){
			updateImageFromNetwork(view, url, ImageUtil.imageMaxSize, ImageUtil.imageMaxSize, ImageUtil.imageMaxSize);
		}else {
			updateImageFromNetwork(view,url, ImageRequest.CacheChoice.DEFAULT);
		}
	}

	public static void updateImageFromNetwork(SimpleDraweeView view, String originUrl, final int width, final int height, final int maxSizeForWH, ImageRequest.CacheChoice cacheChoice, MyBaseControllerListener controllerListener) {
		if (view == null){
			return;
		}
		String url = originUrl;
		if(originUrl != null && originUrl.startsWith("/")){
			url = BASE_IMAGE_URL + originUrl;
		}

		if (TextUtils.isEmpty(url)) {
			view.setTag(url);
			view.setImageURI(url);
			return;
		}
		String viewDispalyUrl = "";
		Object tagObject = view.getTag();
		if (tagObject != null) {
			viewDispalyUrl = (String) tagObject;
		}
		if (url.compareTo(viewDispalyUrl) != 0) {
			view.setTag(url);
			ImageRequestBuilder imageRequestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url));
			if (width > 0 && height > 0 && maxSizeForWH > 0) {
				imageRequestBuilder.setResizeOptions(new ResizeOptions(width, height, maxSizeForWH));
			}
			ImageRequest imageRequest = imageRequestBuilder
					.setImageDecodeOptions(ImageDecodeOptions.newBuilder().setBitmapConfig(Bitmap.Config.RGB_565).build())
					.setCacheChoice(ImageRequest.CacheChoice.DEFAULT)
					.setCacheChoice(cacheChoice)
					.setResizingAllowedOverride(true)
					.build();
			DraweeController draweeController = Fresco.newDraweeControllerBuilder()
					.setImageRequest(imageRequest)
					.setOldController(view.getController())
					.setControllerListener(controllerListener)
					.setAutoPlayAnimations(true)
					.build();
			view.setController(draweeController);
		}
	}

	public static void updateImageFromNetwork(SimpleDraweeView view, String url, ImageRequest.CacheChoice CacheChoice, MyBaseControllerListener controllerListener) {
		if (view == null || TextUtils.isEmpty(url)) {
			view.setTag(url);
			view.setImageURI(url);
			return;
		}
		String viewDispalyUrl = "";
		Object tagObject = view.getTag();
		if (tagObject != null) {
			viewDispalyUrl = (String) tagObject;
		}
		if (url.compareTo(viewDispalyUrl) != 0) {
			view.setTag(url);
			ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
					.setCacheChoice(CacheChoice)
					.build();
			DraweeController draweeController = Fresco.newDraweeControllerBuilder()
					.setImageRequest(imageRequest)
					.setOldController(view.getController())
					.setControllerListener(controllerListener)
					.setAutoPlayAnimations(true)
					.build();
			view.setController(draweeController);
		}
	}

	public static class MyBaseControllerListener implements ControllerListener<ImageInfo> {

		@Override
		public void onSubmit(String id, Object callerContext) {

		}

		@Override
		public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {

		}

		@Override
		public void onIntermediateImageSet(String id, ImageInfo imageInfo) {

		}

		@Override
		public void onIntermediateImageFailed(String id, Throwable throwable) {

		}

		@Override
		public void onFailure(String id, Throwable throwable) {

		}

		@Override
		public void onRelease(String id) {

		}
	}

	public static void updateImageFromNetwork(SimpleDraweeView view, String url, int width, int height, ImageRequest.CacheChoice CacheChoice,
		ControllerListener controllerListener) {
		String viewDispalyUrl = "";
		Object tagObject = view.getTag();
		if (tagObject != null) {
			viewDispalyUrl = (String) tagObject;
		}
		if (url.compareTo(viewDispalyUrl) != 0) {
			view.setTag(url);

			ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
				.setCacheChoice(CacheChoice)
				.setResizeOptions(new ResizeOptions(width, height, 2048f * 5.0f))
				.build();
			DraweeController draweeController = Fresco.newDraweeControllerBuilder()
				.setImageRequest(imageRequest)
				.setOldController(view.getController())
				.setControllerListener(controllerListener)
				.setAutoPlayAnimations(true)
				.build();
			view.setController(draweeController);
		}
	}


	public static Bitmap convertViewToBitmap(View view, int width, int height) {
		if (null == view) {
			return null;
		}
		Bitmap bitmap = null;
		try {
			view.setDrawingCacheEnabled(true);
			view.buildDrawingCache(true);
			if(width != 0 && height != 0){
				view.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
			}else {
				view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
			}
			view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
			view.buildDrawingCache();
			bitmap = view.getDrawingCache(true);
		} catch (Exception e) {
		}
		if (null == bitmap) {
			return null;
		}
		return bitmap;
	}

	public static void insertImageToAlbum(Context context, String path) {
		File file = new File(path);
		if (!file.exists() || file.length() <= 0) { return; }
		insertImageToAlbum(context, path, file.getName());
	}

	/**
	 * 将某一张图片保存到了本地 刷新相册让它出现在相册中
	 *
	 * @param path 图片的本地位置
	 */
	public static void insertImageToAlbum(Context context, String path, String name) {
		File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
		if (dir == null) { return; }
		String cmd = "cp -R " + path + " " + dir.getAbsolutePath();
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(cmd);
			process.waitFor();
		} catch (Exception ignored) {
			if (null != process) {process.destroy();}
		}
		if (null == process || process.exitValue() != 0) { return; }
		Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		Uri uri = Uri.fromFile(new File(dir, name));
		intent.setData(uri);
		context.sendBroadcast(intent);
	}


	/**
	 * 异步读取预加载的图片
	 */
	public static void getBitmap(final int picId, String picUrl, final int width, final int height,
		final BitmapLoadListener bitmapLoadListener) {
		ImageRequestBuilder imageRequestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(picUrl));
		if (width > 0 && height > 0) {
			imageRequestBuilder.setResizeOptions(new ResizeOptions(width, height));
		}
		ImageRequest imageRequest = imageRequestBuilder.setAutoRotateEnabled(true)
			.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
			.setProgressiveRenderingEnabled(false)
			.build();
		ImagePipeline imagePipeline = Fresco.getImagePipeline();
		DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, "ImageUtil");
		dataSource.subscribe(new BaseBitmapDataSubscriber() {
			@Override
			protected void onNewResultImpl(Bitmap bitmap) {
				Bitmap resultBitmap = null;
				if (isBitmapAvailable(bitmap)) {
					try {
						resultBitmap = bitmap.copy(bitmap.getConfig(), bitmap.isMutable());
					} catch (Exception e) {
					}
				}
				if (null == bitmapLoadListener) {
					return;
				}
				bitmapLoadListener.onBitmapLoaded(picId, resultBitmap);
			}

			@Override
			protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
				if (null == bitmapLoadListener) {
					return;
				}
				bitmapLoadListener.onBitmapLoaded(picId, null);
			}
		}, UiThreadImmediateExecutorService.getInstance());
	}
	/**
	 * 异步读取预加载的图片
	 */
	public static void getBitmap(final int picId, String picUrl, final int width, final int height, final int maxSizeForWH,
								 final BitmapLoadListener bitmapLoadListener) {
		ImageRequestBuilder imageRequestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(picUrl));
		if (width > 0 && height > 0) {
			imageRequestBuilder.setResizeOptions(new ResizeOptions(width, height, maxSizeForWH));
			imageRequestBuilder.setResizingAllowedOverride(true);
		}

		ImageRequest imageRequest = imageRequestBuilder.setAutoRotateEnabled(true)
				.setImageDecodeOptions(ImageDecodeOptions.newBuilder().setBitmapConfig(Bitmap.Config.RGB_565).build())
				.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
				.setProgressiveRenderingEnabled(false)
				.build();
		ImagePipeline imagePipeline = Fresco.getImagePipeline();
		DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, "ImageUtil");
		dataSource.subscribe(new BaseBitmapDataSubscriber() {
			@Override
			protected void onNewResultImpl(Bitmap bitmap) {
				Bitmap resultBitmap = null;
				if (isBitmapAvailable(bitmap)) {
					try {
						resultBitmap = bitmap.copy(bitmap.getConfig(), bitmap.isMutable());
					} catch (Exception e) {
					}
				}
				if (null == bitmapLoadListener) {
					return;
				}
				bitmapLoadListener.onBitmapLoaded(picId, resultBitmap);
			}

			@Override
			protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
				if (null == bitmapLoadListener) {
					return;
				}
				bitmapLoadListener.onBitmapLoaded(picId, null);
			}
		}, UiThreadImmediateExecutorService.getInstance());
	}

	public static boolean isBitmapAvailable(Bitmap bitmap) {
		if (null == bitmap || "".equals(bitmap) || bitmap.isRecycled()) {// 如果为null或者是已经回收了的就证明是不可用的
			return false;
		}
		return true;
	}

	public static File obtainCachedPictureFiles(String url){
		try {
			Uri loadUri = Uri.parse(url);
			File localFile = null;
			CacheKey cacheKey = DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(ImageRequest.fromUri(loadUri),null);
			if (ImagePipelineFactory.getInstance().getMainFileCache().hasKey(cacheKey)) {
				BinaryResource resource = ImagePipelineFactory.getInstance().getMainFileCache().getResource(cacheKey);
				assert resource != null;
				localFile = ((FileBinaryResource) resource).getFile();
			} else if (ImagePipelineFactory.getInstance().getSmallImageFileCache().hasKey(cacheKey)) {
				BinaryResource resource = ImagePipelineFactory.getInstance().getSmallImageFileCache().getResource(cacheKey);
				assert resource != null;
				localFile = ((FileBinaryResource) resource).getFile();
			}
			return localFile;
		}catch (Exception e){
			e.printStackTrace();
			Log.e("imageUtils","obtainCachedPictureFiles -- > error");
			return null;
		}
	}

	public static boolean isImageDownloaded(String url) {
		if (url == null || TextUtils.isEmpty(url)) {
			return false;
		}
		CacheKey cacheKey = DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(ImageRequest.fromUri(Uri.parse(url)),null);
		return ImagePipelineFactory.getInstance().getMainFileCache().hasKey(cacheKey) || ImagePipelineFactory.getInstance().getSmallImageFileCache().hasKey(cacheKey);
	}

	public interface BitmapLoadListener {
		void onBitmapLoaded(int id, Bitmap bitmap);
	}
}
